package com.geoai.uimap.core.amap

import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.CoordinateConverter
import com.amap.api.maps.TextureMapView
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.LatLngBounds
import com.geoai.uimap.api.IGEOMap
import com.geoai.uimap.api.IGEOMapCamera
import com.geoai.uimap.core.geomap.bean.GEOMapCameraPosition
import com.geoai.uimap.geo.ILatLng
import com.geoai.uimap.model.GEOLatLng

class GDMapCamera(private val map: GDMap) : IGEOMapCamera {

    override fun getPosition(): GEOLatLng {
        val target = getAMap().cameraPosition.target
        return IGEOMap.getGeoLatlng(map, target)
    }
    override fun getCameraPadding(): DoubleArray? {
        return null
    }

    override fun setPosition(position: ILatLng) {
        getAMap().moveCamera(CameraUpdateFactory.newLatLng(IGEOMap.getGdLatlng(map, position)))
    }

    override fun setPosition(position: ILatLng, level: Float, padding: DoubleArray?) {
        getAMap().moveCamera(CameraUpdateFactory.newLatLngZoom(IGEOMap.getGdLatlng(map, position), level))
    }

    override fun changeBearing(bearValue: Float) {
        getAMap().moveCamera(CameraUpdateFactory.changeBearing(bearValue))
    }

    override fun getCameraPosition(): GEOMapCameraPosition? {
        val cameraP = getAMap().cameraPosition
        val newCameraPosition = GEOMapCameraPosition()
        newCameraPosition.zoom = cameraP.zoom
        newCameraPosition.bearing = cameraP.bearing
        newCameraPosition.target = IGEOMap.getGeoLatlng(map, cameraP.target)
        return newCameraPosition
    }

    override fun getZoomLevel(): Double {
        return getAMap().cameraPosition.zoom.toDouble()
    }

    override fun setZoomLevel(level: Double) {
        val target = getAMap().cameraPosition.target
        getAMap().moveCamera(CameraUpdateFactory.newLatLngZoom(target, level.toFloat()))
    }

    override fun zoomToBounds(bound: List<ILatLng>, padding: Int) {
        val builder = LatLngBounds.Builder()
        bound.forEach {
            val point = IGEOMap.getGdLatlng(map, it)
            builder.include(point)
        }
//        getAMap().moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), dp2px(padding.toFloat())))
        getAMap().moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), padding))
    }

    override fun zoomToBounds(bound: List<ILatLng>, paddingHLeft: Int, paddingVTop: Int, paddingHRight: Int, paddingVBottom: Int) {
        val builder = LatLngBounds.Builder()
        bound.forEach {
            val point = IGEOMap.getGdLatlng(map, it)
            builder.include(point)
        }
//        getAMap().moveCamera(CameraUpdateFactory.newLatLngBoundsRect(builder.build(), dp2px(paddingHLeft.toFloat()), dp2px(paddingHRight.toFloat()) , dp2px(paddingVTop.toFloat()) ,  dp2px(paddingVBottom.toFloat()) ))
        getAMap().moveCamera(CameraUpdateFactory.newLatLngBoundsRect(builder.build(), paddingHLeft, paddingHRight , paddingVTop ,  paddingVBottom))
    }

    override fun getMaxZoomLevel(): Double {
        return getAMap().maxZoomLevel.toDouble()
    }

    override fun getMinZoomLevel(): Double {
        return getAMap().minZoomLevel.toDouble()
    }

    override fun zoomIn() {
        getAMap().moveCamera(CameraUpdateFactory.zoomIn())
    }

    override fun zoomOut() {
        getAMap().moveCamera(CameraUpdateFactory.zoomOut())
    }

    override fun zoomTo(zoom: Double) {
        getAMap().moveCamera(CameraUpdateFactory.zoomTo(zoom.toFloat()))
    }

    private fun getAMap(): AMap {
        return (map.getMapView() as TextureMapView).map
    }

    private fun convert(point: ILatLng): LatLng {
        val converter =
                CoordinateConverter(map.getContext()).from(CoordinateConverter.CoordType.GPS)
        val source = LatLng(point.latitude, point.longitude)
        return converter.coord(source).convert()
    }
}